package com.kexilo.core.common.annotation;

import java.lang.annotation.*;

/**
 * 熔断器注解
 * 用于标记需要熔断保护的方法
 *
 * @author Kexilo
 */
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CircuitBreaker {

    /**
     * 熔断器名称，默认为类名+方法名
     */
    String name() default "";

    /**
     * 失败率阈值（百分比），默认50%
     */
    double failureRateThreshold() default 50.0;

    /**
     * 最小调用次数，默认10次
     * 只有达到最小调用次数后，才会根据失败率判断是否熔断
     */
    int minimumNumberOfCalls() default 10;

    /**
     * 滑动窗口大小，默认100次调用
     */
    int slidingWindowSize() default 100;

    /**
     * 滑动窗口类型
     */
    SlidingWindowType slidingWindowType() default SlidingWindowType.COUNT_BASED;

    /**
     * 半开状态下允许的调用次数，默认10次
     */
    int permittedNumberOfCallsInHalfOpenState() default 10;

    /**
     * 熔断器从开启状态到半开状态的等待时间（秒），默认60秒
     */
    long waitDurationInOpenState() default 60;

    /**
     * 慢调用时间阈值（毫秒），默认60秒
     */
    long slowCallDurationThreshold() default 60000;

    /**
     * 慢调用率阈值（百分比），默认100%
     */
    double slowCallRateThreshold() default 100.0;

    /**
     * 熔断时的降级方法名
     */
    String fallbackMethod() default "";

    /**
     * 需要记录为失败的异常类型
     */
    Class<? extends Throwable>[] recordExceptions() default {Exception.class};

    /**
     * 需要忽略的异常类型
     */
    Class<? extends Throwable>[] ignoreExceptions() default {};

    /**
     * 滑动窗口类型
     */
    enum SlidingWindowType {
        /** 基于调用次数 */
        COUNT_BASED,
        /** 基于时间 */
        TIME_BASED
    }
}
